package root.electronclass.electronclass.grade

import android.content.res.ColorStateList
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.google.android.material.tabs.TabLayout.Tab
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import root.electronclass.electronclass.R
import root.electronclass.electronclass.common.base.BasicAdapter
import root.electronclass.electronclass.common.base.ViewBindingFragment
import root.electronclass.electronclass.databinding.FragmentClassIndex4Binding
import root.electronclass.electronclass.databinding.FragmentClassIndex9ItemBinding
import root.electronclass.electronclass.databinding.FragmentClassIndexBinding
import root.electronclass.electronclass.ext.*
import root.electronclass.electronclass.grade.widget.BarChartItem
import root.electronclass.electronclass.grade.widget.CircleItem
import root.electronclass.electronclass.grade.widget.PillarChartView
import root.electronclass.electronclass.mvp.GlobalParameter
import root.electronclass.electronclass.mvp.base.data
import root.electronclass.electronclass.mvp.base.isSuccessful
import root.electronclass.electronclass.mvp.rest.ClassApi
import root.electronclass.electronclass.mvp.rest.RestManager
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.Locale

/**
 *
 * @author Lokiy
 * @date 2023/1/8 15:49
 */
@Suppress("FunctionName")
class ClassIndexFragment : ViewBindingFragment<FragmentClassIndexBinding>() {
    private val decimalFormat = DecimalFormat("0.##", DecimalFormatSymbols(Locale.CHINA))

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        loadData()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (hidden.not() && view != null) {
            loadData()
        }
    }

    private fun loadData() {
        //第一块 班级信息
        initClassInfo()
        //第三块 班级作业
        initHomework()
        //第四块 班级排名
        initRankLayout()
        //第五块 学生状态
        initSign()
        //第六块 学生状态统计
        initStudentStatus()
    }

    private fun initClassInfo() {
        lifecycleScope.launch(CoroutineExceptionHandler()) {
            withContext(Dispatchers.IO) {
                RestManager.getInstance().classRest().getIndexClassInfo()
            }?.rows?.let {
                binding.include1.tvClassName.text = GlobalParameter.getEcardInfo().className
                binding.include1.classSlogan.text = it.motto

                binding.include1.classNumMax.text = getString(R.string.class_max, it.classNum)
                binding.include1.progress.progress = it.presentNum / it.classNum.toFloat() * 100
                binding.include1.tvProgress.text = decimalFormat.format(binding.include1.progress.progress)
                binding.include1.classNum.text = it.presentNum.toString()

                binding.include1.classNumType1.text = it.fwzx.toString()
                binding.include1.classNumType2.text = it.wzx.toString()
                binding.include1.classNumType3.text = it.zxs.toString()
                binding.include1.progress.isShowItemText = false
                binding.include1.progress.isRoundEdgeProgress = true
            }
        }
    }

    private fun initNotification(rankBinding: FragmentClassIndex4Binding) {
        lifecycleScope.launch(RankCoroutineExceptionHandler(rankBinding)) {
            val result = withContext(Dispatchers.IO) {
                RestManager.getInstance().classRest().getIndexNoticeRank()
            }
            if (result.isSuccessful) {
                val data = result.data
                rankBinding.numLayout.num.text = data.total.toString()
                //年纪比
                rankBinding.gradeRankLayout.fill(requireContext(), R.string.class_rank_grade, data.gradeRank2, data.gradeRank1)
                //全校比
                rankBinding.schoolRankLayout.fill(requireContext(), R.string.class_rank_school, data.schoolRank2, data.schoolRank1)
            } else {
                rankBinding.numLayout.num.text = "0"
                rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
                rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
            }
        }
    }

    private fun initHomework() {
        lifecycleScope.launch(CoroutineExceptionHandler()) {
            withContext(Dispatchers.IO) {
                RestManager.getInstance().classRest().getIndexHomeworkChart()
            }?.rows?.let { chart ->

                binding.include3.homeworkChart.setData(chart.avgHour?.map { it["name"]!! to it["value"]!!.toFloat() })

                val weekList = mutableListOf("周一", "周二", "周三", "周四", "周五", "周六", "周日")
                val finishData = mutableListOf<Float>()
                val unFinishData = mutableListOf<Float>()
                chart.homeworkWeek?.values?.forEach {
                    finishData.add(it["finish"]?.toFloat() ?: 0f)
                    unFinishData.add(it["unFinish"]?.toFloat() ?: 0f)
                }
                binding.include3.lineChart.horizontalLineCount = 6
                binding.include3.lineChart.data += PillarChartView.LineChartData(
                    ContextCompat.getColor(binding.root.context, R.color.c_brand),
                    unFinishData
                )
                binding.include3.lineChart.data += PillarChartView.LineChartData(0xFF19C5FF.toInt(), finishData)
                binding.include3.lineChart.yFormatter = { weekList.getOrNull(it) ?: "" }
                binding.include3.lineChart.invalidate()
            }
        }
//        binding.include3.homeworkChart.setData(arrayOf("语文", "数学", "英语", "体育", "美术", "音乐", "科学").map { it to Random.nextInt(1000).toFloat() })
    }

    private fun initRankLayout() {
        val titles = arrayOf(R.string.class_title_4, R.string.class_title_5, R.string.class_title_6, R.string.class_title_7, R.string.class_title_8, R.string.class_notification)
        val tips = arrayOf(R.string.class_tips_4, R.string.class_tips_5, R.string.class_tips_6, R.string.class_tips_7, R.string.class_tips_8, R.string.class_notification_total_publish)
        val unit =
            arrayOf(R.string.class_unit, R.string.class_unit_score, R.string.class_unit_percent, R.string.class_unit, R.string.class_unit_count, R.string.class_unit_count1)
        arrayOf(binding.include4, binding.include5, binding.include6, binding.include7, binding.include8, binding.include2).forEachIndexed { index, rankBinding ->
            val title = titles[index]
            rankBinding.cardTitle.setText(title)
            when (title) {
                R.string.class_title_4 -> {
                    initExcellentStudent(rankBinding)
                }
                R.string.class_title_5 -> {
                    initExcellent(rankBinding)
                }
                R.string.class_title_7 -> {
                    initHonor(rankBinding)
                }
                R.string.class_title_6 -> {
                    lifecycleScope.launch(RankCoroutineExceptionHandler(rankBinding)) {
                        val result = withContext(Dispatchers.IO) {
                            RestManager.getInstance().classRest().getIndexAttnRank()
                        }
                        if (result.isSuccessful) {
                            val data = result.data
                            rankBinding.numLayout.num.text = data.total.toString()
                            rankBinding.extraNumLayout.num.text = data.unSign.toString()
                            //年纪比
                            rankBinding.gradeRankLayout.fill(requireContext(), R.string.class_rank_grade, data.gradeRank2, data.gradeRank1)
                            //全校比
                            rankBinding.schoolRankLayout.fill(requireContext(), R.string.class_rank_school, data.schoolRank2, data.schoolRank1)

                            //班级考勤
                            rankBinding.extraNumLayout.root.isVisible = true
                            rankBinding.extraNumLayout.numTips.setText(R.string.class_tips_6_2)
                            rankBinding.extraNumLayout.num.setTextColor(resources.getColor(R.color.c_ff503d))
                            rankBinding.extraNumLayout.numUnit.setText(R.string.class_unit)
                        } else {
                            rankBinding.numLayout.num.text = "0"
                            rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
                            rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
                        }
                    }
                }
                R.string.class_title_8 -> {
                    initClassStore(rankBinding)
                }
                R.string.class_notification -> {
                    initNotification(rankBinding)
                }
            }
            rankBinding.numLayout.numTips.setText(tips[index])
            rankBinding.numLayout.numUnit.setText(unit[index])
        }
    }

    private fun initClassStore(rankBinding: FragmentClassIndex4Binding) {
        lifecycleScope.launch(RankCoroutineExceptionHandler(rankBinding)) {
            val result = withContext(Dispatchers.IO) {
                RestManager.getInstance().classRest().getIndexCatchRank()
            }
            if (result.isSuccessful) {
                val data = result.data
                rankBinding.numLayout.num.text = data.total.toString()
                //年纪比
                rankBinding.gradeRankLayout.fill(requireContext(), R.string.class_rank_grade, data.gradeRank2, data.gradeRank1)
                //全校比
                rankBinding.schoolRankLayout.fill(requireContext(), R.string.class_rank_school, data.schoolRank2, data.schoolRank1)
            } else {
                rankBinding.numLayout.num.text = "0"
                rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
                rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
            }
        }
    }

    private fun initHonor(rankBinding: FragmentClassIndex4Binding) {
        val onTabClick: (Tab) -> Unit = {
            lifecycleScope.launch(RankCoroutineExceptionHandler(rankBinding)) {
                val result = withContext(Dispatchers.IO) {
                    RestManager.getInstance().classRest().getIndexHonorRank(it.tag as Int)
                }
                if (result.isSuccessful) {
                    val data = result.data
                    rankBinding.numLayout.num.text = data.total.toString()
                    rankBinding.extraNumLayout.num.text = data.unSign.toString()
                    //年纪比
                    rankBinding.gradeRankLayout.fill(requireContext(), R.string.class_rank_grade, data.gradeRank2, data.gradeRank1)
                    //全校比
                    rankBinding.schoolRankLayout.fill(requireContext(), R.string.class_rank_school, data.schoolRank2, data.schoolRank1)
                } else {
                    rankBinding.numLayout.num.text = "0"
                    rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
                    rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
                }
            }
        }
        rankBinding.tab.let {
            it.isVisible = false
            if (it.tabCount > 0) return@let onTabClick.invoke(it.getTabAt(it.selectedTabPosition) ?: return)
            it.addTab(it.newTab().setText(R.string.class_7_tab_0).setTag(2))
            it.addTab(it.newTab().setText(R.string.class_7_tab_1).setTag(1))
            onTabClick.invoke(it.getTabAt(0)!!)
            it.doOnTabSelected { tab ->
                tab ?: return@doOnTabSelected
                onTabClick.invoke(tab)
            }
        }
    }

    private fun initExcellent(rankBinding: FragmentClassIndex4Binding) {
        val onTabClick: (Tab) -> Unit = {
            lifecycleScope.launch(RankCoroutineExceptionHandler(rankBinding)) {
                val result = withContext(Dispatchers.IO) {
                    val type = it.tag as Int
                    if (type == 1) {
                        ClassApi.service.getIndexMoralScoreRecordCompetitionScoreList()
                    } else {
                        ClassApi.service.getIndexMoralScoreRecordStudentScoreList()
                    }
                }
                if (result.isSuccessful) {
                    val data = result.data
                    rankBinding.numLayout.num.text = data.score
                    //年纪比
                    rankBinding.gradeRankLayout.fill(requireContext(), R.string.class_rank_grade, data.gradeRank.orEmpty(), data.gradeUpOrDown)
                    //全校比
                    rankBinding.schoolRankLayout.fill(requireContext(), R.string.class_rank_school, data.schoolRank.orEmpty(), data.schoolUpOrDown)
                } else {
                    rankBinding.numLayout.num.text = "0"
                    rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
                    rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
                }
            }
        }
        rankBinding.tab.let {
            it.isVisible = false
            if (it.tabCount > 0) return@let onTabClick.invoke(it.getTabAt(it.selectedTabPosition) ?: return)
            it.addTab(it.newTab().setText(R.string.class_4_tab_0).setTag(2))
            it.addTab(it.newTab().setText(R.string.class_4_tab_2).setTag(1))
            onTabClick.invoke(it.getTabAt(0)!!)
            it.doOnTabSelected { tab ->
                tab ?: return@doOnTabSelected
                onTabClick.invoke(tab)
            }
        }
    }

    private fun initExcellentStudent(rankBinding: FragmentClassIndex4Binding) {
        val onTabClick: (Tab) -> Unit = {
            lifecycleScope.launch(RankCoroutineExceptionHandler(rankBinding)) {
                val result = withContext(Dispatchers.IO) {
                    val type = it.tag as Int
                    if (type == 1) {
                        ClassApi.service.getIndexMoralStudentScoreCompetitionList()
                    } else {
                        ClassApi.service.getIndexMoralStudentScoreList()
                    }
                }
                if (result.isSuccessful) {
                    val data = result.data
                    rankBinding.numLayout.num.text = data.peopleNum.toString()
                    //年纪比
                    rankBinding.gradeRankLayout.fill(requireContext(), R.string.class_rank_grade, data.gradeRank.orEmpty(), data.gradeUpOrDown)
                    //全校比
                    rankBinding.schoolRankLayout.fill(requireContext(), R.string.class_rank_school, data.schoolRank.orEmpty(), data.schoolUpOrDown)
                } else {
                    rankBinding.numLayout.num.text = "0"
                    rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
                    rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
                }
            }
        }
        rankBinding.tab.let {
            if (it.tabCount > 0) return@let onTabClick.invoke(it.getTabAt(it.selectedTabPosition) ?: return)
            it.addTab(it.newTab().setText(R.string.class_4_tab_0).setTag(2))
            it.addTab(it.newTab().setText(R.string.class_4_tab_2).setTag(1))
            onTabClick.invoke(it.getTabAt(0)!!)
            it.doOnTabSelected { tab ->
                tab ?: return@doOnTabSelected
                onTabClick.invoke(tab)
            }
        }
    }

    private fun RankCoroutineExceptionHandler(rankBinding: FragmentClassIndex4Binding) = CoroutineExceptionHandler {
        rankBinding.numLayout.num.text = "0"
        rankBinding.gradeRankLayout.showEmpty(R.string.class_rank_grade)
        rankBinding.schoolRankLayout.showEmpty(R.string.class_rank_school)
    }

    private fun initStudentStatus() {
        lifecycleScope.launch(CoroutineExceptionHandler()) {
            withContext(Dispatchers.IO) {
                RestManager.getInstance().classRest().getIndexDepartStudentStat()
            }?.rows?.let {
                val list = arrayListOf<CircleItem>().apply {
                    add(CircleItem(0xFF5B8FF9.toInt(), it.school))
                    add(CircleItem(0xFF5AD8A6.toInt(), it.person))
                    add(CircleItem(0xFF5D7092.toInt(), it.sick))
                    add(CircleItem(0xFFF6BD16.toInt(), it.other))
                }
                val names = arrayOf("在校人数 ${it.school}人", "事假人数 ${it.person}人", "病假人数 ${it.sick}人", "其他 ${it.other}人")
                binding.include9.classStatusChart.setData(list)
                binding.include9.recycler.adapter = BasicAdapter<CircleItem, FragmentClassIndex9ItemBinding> { holder, item ->
                    holder.binding.itemDot.imageTintList = ColorStateList.valueOf(item.color)
                    holder.binding.itemName.text = names.getOrNull(holder.adapterPosition)
                }.also { it.refresh(list) }
            }
        }
    }

    private fun initSign() {
        binding.include10.cardTitle.setText(R.string.class_sign)
        lifecycleScope.launch(CoroutineExceptionHandler()) {
            val list = withContext(Dispatchers.IO) {
                ClassApi.service.getIndexSchoolCourseSignList()?.rows ?: mutableListOf()
            }.mapIndexed { index, classSignStat ->
                BarChartItem(classSignStat.subjectName, classSignStat.signCount.toFloat() / classSignStat.signAllCount.coerceAtLeast(1) * 100)
            }

            val chart = binding.include10.barChart
            chart.setData(list)
//            listOf(
//                BarChartItem("语文", 95.6f),
//                BarChartItem("数学", 94.1f),
//                BarChartItem("英语", 92f),
//                BarChartItem("化学", 90f),
//                BarChartItem("物理", 89f),
//                BarChartItem("体育", 67.2f),
//                BarChartItem("政治", 54f)
//            )
        }
    }

}